<?php

// 假设原始数据如下  
$data = array(  
    array('Product', 'Category', 'Price'),  
    array('Apple', 'Fruit', 1.5),  
    array('Banana', 'Fruit', 0.5),  
    array('Carrot', 'Vegetable', 0.75),  
    array('Lettuce', 'Vegetable', 1.0),  
);  
  
// 透视表函数  
function pivotTable($data, $rows, $cols) {  
    $pivotTable = array();  
  
    // 构建透视表  
    foreach ($data as $row) {  
        $rowData = array_combine($rows, array_slice($row, 0, count($rows)));  
        $pivotRow = &$pivotTable[implode('-', $rowData)];  
  
        foreach ($cols as $i => $col) {  
            $colData = $row[$i + count($rows)];  
            $pivotRow[$col] = $colData;  
        }  
    }  
  
    return $pivotTable;  
}  
  
// 选择透视表的行和列  
$rows = array('Product');  
$cols = array('Category', 'Price');  
  
// 生成透视表  
$pivotTable = pivotTable($data, $rows, $cols);  

var_dump($pivotTable);
// 打印透视表  
foreach ($pivotTable as $row => $rowData) {  
    echo $row . "\n";  
    foreach ($rowData as $col => $value) {  
        echo "\t" . $col . ": " . $value . "\n";  
    }  
    echo "\n";  
}
function array_group_by(array $arr, $key) : array
{
    if (!is_string($key) && !is_int($key) && !is_float($key) && !is_callable($key)) {
        trigger_error('array_group_by(): The key should be a string, an integer, a float, or a function', E_USER_ERROR);
    }

    $isFunction = !is_string($key) && is_callable($key);

    // Load the new array, splitting by the target key
    $grouped = [];
    foreach ($arr as $value) {
        $groupKey = null;

        if ($isFunction) {
            $groupKey = $key($value);
        } else if (is_object($value)) {
            $groupKey = $value->{$key};
        } else {
            $groupKey = $value[$key];
        }

        $grouped[$groupKey][] = $value;
    }

    // Recursively build a nested grouping if more parameters are supplied
    // Each grouped array value is grouped according to the next sequential key
    if (func_num_args() > 2) {
        $args = func_get_args();

        foreach ($grouped as $groupKey => $value) {
            $params = array_merge([$value], array_slice($args, 2, func_num_args()));
            $grouped[$groupKey] = call_user_func_array('array_group_by', $params);
        }
    }

    return $grouped;
}


$records = [
    [
        'state'  => 'IN',
        'city'   => 'Indianapolis',
        'object' => 'School bus',
    ],
    [
        'state'  => 'IN',
        'city'   => 'Indianapolis',
        'object' => 'Manhole',
    ],
    [
        'state'  => 'IN',
        'city'   => 'Plainfield',
        'object' => 'Basketball',
    ],
    [
        'state'  => 'CA',
        'city'   => 'San Diego',
        'object' => 'Light bulb',
    ],
    [
        'state'  => 'CA',
        'city'   => 'Mountain View',
        'object' => 'Space 1',
    ],    [
        'state'  => 'CA',
        'city'   => 'Mountain View',
        'object' => 'Space 2',
    ],    [
        'state'  => 'CA',
        'city'   => 'Mountain View',
        'object' => 'Space pen',
    ],
];

$grouped = array_group_by($records, 'state', 'city');var_dump($grouped);